package com.lingchou.cloud.process.client.controller;

import cn.hutool.core.util.StrUtil;
import com.lc.common.bean.response.Result;
import com.lingchou.cloud.process.api.controller.ProcessHistoryApi;
import com.lingchou.cloud.process.api.dto.result.HistoricProcessInstanceDTO;
import com.lingchou.cloud.process.api.dto.result.HistoricTaskInstanceDTO;
import com.lingchou.cloud.process.client.service.ProcessCheckService;
import com.lingchou.cloud.process.client.service.ProcessUtilService;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@Validated
public class ProcessHistoryApiImpl implements ProcessHistoryApi {

    private final HistoryService historyService;
    private final ProcessUtilService processUtilService;
    private final ProcessCheckService processCheckService;

    public ProcessHistoryApiImpl(HistoryService historyService, ProcessUtilService processUtilService, ProcessCheckService processCheckService) {
        this.historyService = historyService;
        this.processUtilService = processUtilService;
        this.processCheckService = processCheckService;
    }

    @Override
    public Result<List<HistoricTaskInstanceDTO>> historicTaskListByInvoker(String userId, String businessKey) {
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().finished();
        //匹配业务KEY
        if (!StrUtil.isEmpty(businessKey)) {
            query.processInstanceBusinessKey(businessKey);
        }
        //匹配执行人或者归属人
        if (!StrUtil.isEmpty(userId)) {
            query.or().taskAssignee(userId).taskOwner(userId).endOr();
        }
        List<HistoricTaskInstanceDTO> historicTaskInstances = processUtilService.buildHistoricTaskInstanceDTOList(query.list());
        return Result.successPage(historicTaskInstances, historicTaskInstances.size(), 0);
    }

    @Override
    public Result<List<HistoricTaskInstanceDTO>> historicTaskListByInvokerAndKeyLike(String userId, String businessKey, String key) {
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().finished();
        //匹配业务KEY
        if (!StrUtil.isEmpty(businessKey)) {
            query.processInstanceBusinessKey(businessKey);
        }
        if (!StrUtil.isEmpty(key)) {
            query.taskDefinitionKeyLike("%" + key + "%");
        }
        //匹配执行人或者归属人
        if (!StrUtil.isEmpty(userId)) {
            query.or().taskAssignee(userId).taskOwner(userId).endOr();
        }
        List<HistoricTaskInstanceDTO> historicTaskInstances = processUtilService.buildHistoricTaskInstanceDTOList(query.list());
        return Result.successPage(historicTaskInstances, historicTaskInstances.size(), 0);
    }

    @Override
    public Result<List<HistoricTaskInstanceDTO>> historicTaskListByInvokerForUser(String assignee, String owner, String businessKey) {
        //匹配已完成 执行人
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().finished().taskAssignee(assignee);
        //匹配业务KEY
        if (!StrUtil.isEmpty(businessKey)) {
            query.processInstanceBusinessKey(businessKey);
        }
        //匹配执行人或者归属人
        if (!StrUtil.isEmpty(owner)) {
            query.taskOwner(owner);
        }
        List<HistoricTaskInstance> historicTaskInstanceList = query.list().stream()
                .filter(h -> !h.getOwner().equals(assignee)).collect(Collectors.toList());
        List<HistoricTaskInstanceDTO> historicTaskInstances = processUtilService.buildHistoricTaskInstanceDTOList(historicTaskInstanceList);
        return Result.successPage(historicTaskInstances, historicTaskInstances.size(), 0);
    }

    @Override
    public Result<List<HistoricTaskInstanceDTO>> historicTaskListByInvokerForUser(String assignee, String owner, String businessKey, String key) {
        //匹配已完成 执行人
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().finished().taskAssignee(assignee);
        //匹配业务KEY
        if (!StrUtil.isEmpty(businessKey)) {
            query.processInstanceBusinessKey(businessKey);
        }
        //匹配任务KEY
        if (!StrUtil.isEmpty(key)) {
            query.taskDefinitionKeyLike("%" + key + "%");
        }
        //匹配执行人或者归属人
        if (!StrUtil.isEmpty(owner)) {
            query.taskOwner(owner);
        }
        List<HistoricTaskInstance> historicTaskInstanceList = query.list().stream()
                .filter(h -> !h.getOwner().equals(assignee)).collect(Collectors.toList());
        List<HistoricTaskInstanceDTO> historicTaskInstances = processUtilService.buildHistoricTaskInstanceDTOList(historicTaskInstanceList);
        return Result.successPage(historicTaskInstances, historicTaskInstances.size(), 0);
    }

    @Override
    public Result<List<HistoricProcessInstanceDTO>> historicProcessListByInvoker(String userId, String businessKey) {
        HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
        if (!StrUtil.isEmpty(businessKey)) {
            query.processInstanceBusinessKey(businessKey);
        }
        if (!StrUtil.isEmpty(userId)) {
            query.involvedUser(userId);
        }
        List<HistoricProcessInstanceDTO> processInstanceDTOS = processUtilService.buildHistoricProcessInstanceDTOList(query.list());
        return Result.successPage(processInstanceDTOS, processInstanceDTOS.size(), 0);
    }

    @Override
    public Result<List<HistoricProcessInstanceDTO>> historicProcessListByStarter(String userId, Integer startNum, Integer rows) {
        HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
        if (!StrUtil.isEmpty(userId)) {
            query.startedBy(userId);
        }
        query.finished().orderByProcessInstanceEndTime().desc();
        List<HistoricProcessInstance> historicProcessInstances;
        if (startNum != null && rows != null) {
            rows += startNum;
            historicProcessInstances = query.listPage(startNum, rows);
        } else {
            historicProcessInstances = query.list();
        }
        return Result.success(processUtilService.buildHistoricProcessInstanceDTOList(historicProcessInstances));
    }

    @Override
    public Result<List<HistoricTaskInstanceDTO>> historicTasksForProcessInstance(String processInstanceId) {
        if (processCheckService.checkProcessInstanceInvalid(processInstanceId, false)) {
            return Result.failure("流程实例不存在");
        }
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId).finished().orderByHistoricTaskInstanceEndTime().asc().list();
        return Result.success(processUtilService.buildHistoricTaskInstanceDTOList(historicTaskInstances));
    }
}